﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CruzDelSur.Models;
using CruzDelSur.Dominio;
using CruzDelSur.Dominio.Seguridad;
using CruzDelSur.Persistencia;
using System.Web.Mvc;
using System.Data.SqlTypes;
using System.Globalization;

namespace CruzDelSur.Negocio
{
    public class AdministrarRecursosService
    {
        IServicioDAO ServicioDAO { get; set; }
        IVehiculoDAO VehiculoDAO { get; set; }
        ITripulacionDAO TripulacionDAO { get; set; }
        IFlotaCargaDAO FlotaCargaDAO { get; set; }
        IFlotaPasajeroDAO FlotaPasajeroDAO { get; set; }

        //public AdministrarRecursosService()
        //{

        //}
        //Flota Pasajero
        

        
  public FlotaPasajero crearFlotaPasajero(FlotaPasajero nuevaFlotaPasajero)
  {
    //Como vamos a trabajr sin validaciones no voy a poner flujos alternos,
    //simulare qye todo es bajo condiciones ideales

    nuevaFlotaPasajero.FechaCreado = DateTime.Now;
    nuevaFlotaPasajero.ModificadoPor = "";
    nuevaFlotaPasajero.FechaModificado = SqlDateTime.MinValue.Value;
    nuevaFlotaPasajero.FechaBaja= SqlDateTime.MinValue.Value;
    nuevaFlotaPasajero.Estado = Servicio.PENDIENTE;        
    FlotaPasajeroDAO.Crear(nuevaFlotaPasajero);
    return nuevaFlotaPasajero;
  }
      
  public FlotaPasajero modificarFlotaPasajero(FlotaPasajero nuevoFlotaPasajero)
  {
    FlotaPasajero editFlotaPasajero = FlotaPasajeroDAO.obtenerFlotaPasajero(nuevoFlotaPasajero.CodigoUnidadTransporte, nuevoFlotaPasajero.CodigoServicio);

    editFlotaPasajero.FlagBusCama = nuevoFlotaPasajero.FlagBusCama;
    editFlotaPasajero.NumeroEjes = nuevoFlotaPasajero.NumeroEjes;
    editFlotaPasajero.Numeroreclinable160 = nuevoFlotaPasajero.Numeroreclinable160;
    editFlotaPasajero.Numeroreclinable180 = nuevoFlotaPasajero.Numeroreclinable180;
    editFlotaPasajero.ModificadoPor = nuevoFlotaPasajero.ModificadoPor;
    editFlotaPasajero.NumeroPisos = nuevoFlotaPasajero.NumeroPisos;
    editFlotaPasajero.Numeroasientos = nuevoFlotaPasajero.Numeroasientos;
    FlotaPasajeroDAO.Modificar(editFlotaPasajero);
    return editFlotaPasajero;
  }


        public ListadoFlotaPasajeroModel obtenerListadoFlotaPasajero()
        {
            return new ListadoFlotaPasajeroModel 
            {
                FlotaPasajeros= FlotaPasajeroDAO.obtenerListado()
            };
        }


        #region flotacarga
               
        public FlotaCargasModel crearNuevoFlotaCargaModel()
        {
            FlotaCargasModel model = new FlotaCargasModel();
            model.FlotaCarga = new FlotaCarga();
            model.FlotaCarga.Estado = Servicio.PENDIENTE;
            model.Vehiculos = new SelectList(VehiculoDAO.listarVehiculos(), "Codigo", "Nombre");
            return model;
        }

        public FlotaCargasModel abrirFlotaCargaModel(string codFlotaCarga)
        {
            FlotaCargasModel model = crearNuevoFlotaCargaModel();
            FlotaCarga flotacarga = FlotaCargaDAO.Obtener(codFlotaCarga);
            model.FlotaCarga = flotacarga;
            model.Vehiculos = obtenerComboVehiculos(flotacarga.Vehiculo.Codigo);
            return model;
        }
       
        public FlotaCarga crearFlotaCarga(FlotaCarga nuevoFlotaCarga)
        {
            if (nuevoFlotaCarga.Codigo.Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código válido");
            }
            if (FlotaCargaDAO.Obtener(nuevoFlotaCarga.Codigo) != null)
            {
                throw new ServicioExistenteException("Código ya existe");
            }
            nuevoFlotaCarga.FechaCreado = DateTime.Now;
            nuevoFlotaCarga.FechaModificado = SqlDateTime.MinValue.Value;
            nuevoFlotaCarga.FechaBaja = SqlDateTime.MinValue.Value;
            FlotaCargaDAO.Crear(nuevoFlotaCarga);
            return nuevoFlotaCarga;
        }

        public ListadoFlotaCargaModel obtenerListadoFlotaCarga()
        {
            return new ListadoFlotaCargaModel
            {
                FlotaCargas = FlotaCargaDAO.obtenerListado()
            };
        }

        public FlotaCarga modificarFlotaCarga(FlotaCarga nuevoFlotaCarga)
        {
            FlotaCarga editFlotaCarga = FlotaCargaDAO.Obtener(nuevoFlotaCarga.Codigo);
            //editFlotaCarga.Vehiculo = nuevoFlotaCarga.Vehiculo;
            editFlotaCarga.Vehiculo = VehiculoDAO.Obtener(nuevoFlotaCarga.Vehiculo.Codigo);
            editFlotaCarga.Tara = nuevoFlotaCarga.Tara;
            editFlotaCarga.AltoBodega = nuevoFlotaCarga.AltoBodega;
            editFlotaCarga.AnchoBodega = nuevoFlotaCarga.AnchoBodega;
            editFlotaCarga.LargoBodega = nuevoFlotaCarga.LargoBodega;
            editFlotaCarga.VolumenBodega = nuevoFlotaCarga.VolumenBodega;
            editFlotaCarga.FechaBaja = SqlDateTime.MinValue.Value;
            editFlotaCarga.FechaModificado = DateTime.Now;
            FlotaCargaDAO.Modificar(editFlotaCarga);
            return editFlotaCarga;
        }

        public bool darBajaFlotaCarga(string codigo, DateTime fecha, Usuario user)
        {
            if (codigo.Trim().Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código válido");
            }
            //Regla de negocio - SE_RN_12
            if (!this.RN_FechaBajaValido(fecha))
            {
                throw new FechaBajaServicioInvalidoException("Las bajas de Flota Carga deben tener una fecha de inicio de baja mayor por 2 meses al día que se registra la baja");
            }
            FlotaCarga s = FlotaCargaDAO.Obtener(codigo);
            if (s != null)
            {
                //ServicioTramoDAO.DarBaja(s.Codigo, s.FechaBaja);
                s.FechaBaja = fecha;
                s.FechaModificado = DateTime.Now;
                s.ModificadoPor = user.Codigo;
                s.Estado = Servicio.INACTIVO;
                FlotaCargaDAO.Modificar(s);
            }
            else
            {
                throw new CodigoInvalidoException("Código no existe");
            }
            return true;
        }

        public FlotaCargasModel darBajaFlotaCargaModel(string codFlotaCarga, FlotaCargaEstadoEnum estado)
        {
            FlotaCargasModel model = new FlotaCargasModel
            {
                FlotaCarga = obtenerFlotaCarga(codFlotaCarga),
                EstadoEdicion = estado,
            };
            model.FlotaCarga.FechaBaja = DateTime.Now.AddMonths(2);
            return model;
        }

        public FlotaCarga obtenerFlotaCarga(string Codigo)
        {
            return FlotaCargaDAO.Obtener(Codigo);
        }

        #endregion
        
        public string formatoFecha()
        {
            string format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.ToLower();
            return format.Replace("yyyy", "yy");
        }

        public bool RN_FechaBajaValido(DateTime fecha)
        {
            return fecha >= DateTime.Now.AddMonths(2);
        }

        public ICollection<Tripulacion> listadoTripulacion(){
            return TripulacionDAO.listadoTripulacion();
        }

        public ListadoTripulacionModel obtenerListadoTripulacion()
        {
            return new ListadoTripulacionModel
            {
                Tripulaciones = TripulacionDAO.listadoTripulacion()
            };
        }

        public SelectList obtenerComboVehiculos(string selectedValue)
        {
            return new SelectList(VehiculoDAO.listarVehiculos(), "Codigo", "Nombre", selectedValue);
        }

        public Tripulacion obtenerTripulacion(string CodigoEmpleado, string CodigoCargo)
        {
            return TripulacionDAO.obtenerTripulacion(new TripulacionCargoId(CodigoEmpleado, CodigoCargo));
        }

        public Tripulacion crearTripulacion(Tripulacion trip)
        {
            trip.Estado = Servicio.PENDIENTE;
            trip.FechaBaja = SqlDateTime.MinValue.Value;
            trip.FechaCreado = DateTime.Now;
            trip.FechaModificado = SqlDateTime.MinValue.Value;
            return TripulacionDAO.Crear(trip);
        }

        public Tripulacion modificarTripulacion(TripulacionCargoId actual, Tripulacion newTrip)
        {
            Tripulacion t = TripulacionDAO.obtenerTripulacion(actual);
            TripulacionDAO.eliminarTripulacion(actual);
            t.FechaModificado = SqlDateTime.MinValue.Value;
            t.CodigoCargo = newTrip.CodigoCargo;
            t.UsuarioModificado = newTrip.UsuarioModificado;
            return TripulacionDAO.Crear(t);
        }

        public bool darBajaTripulacion(Tripulacion trip)
        {
            if (trip.CodigoEmpleado.Trim().Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código de empleado válido");
            }
            if (trip.CodigoCargo.Trim().Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código de cargo válido");
            }
            //Regla de negocio - SE_RN_12
            if (!this.RN_FechaBajaValido(trip.FechaBaja))
            {
                throw new FechaBajaServicioInvalidoException("Las bajas de tripulantes deben tener una fecha de inicio de baja mayor por 2 meses al día que se registra la baja");
            }
            Tripulacion t = TripulacionDAO.obtenerTripulacion(new TripulacionCargoId(trip.CodigoEmpleado, trip.CodigoCargo));
            if (t != null)
            {
                t.FechaBaja = trip.FechaBaja;
                t.FechaModificado = DateTime.Now;
                t.Estado = Servicio.INACTIVO;
                TripulacionDAO.Modificar(t);
            }
            else
            {
                throw new CodigoInvalidoException("Código no existe");
            }
            return true;
        }

        public bool darBajaFlotaPasajero(FlotaPasajero flota)
        {
            if (flota.CodigoUnidadTransporte.Trim().Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código de unidad válido");
            }
            if (flota.CodigoServicio.Trim().Equals(""))
            {
                throw new CodigoInvalidoException("Debe ingresar un código de servicio válido");
            }
            //Regla de negocio - SE_RN_12
            if (!this.RN_FechaBajaValido(flota.FechaBaja))
            {
                throw new FechaBajaServicioInvalidoException("Las bajas de flotas deben tener una fecha de inicio de baja mayor por 2 meses al día que se registra la baja");
            }
            FlotaPasajero f = FlotaPasajeroDAO.obtenerFlotaPasajero(flota.CodigoUnidadTransporte, flota.CodigoServicio);
            if (f != null)
            {
                f.FechaBaja = flota.FechaBaja;
                f.FechaModificado = DateTime.Now;
                f.Estado = Servicio.INACTIVO;
                FlotaPasajeroDAO.Modificar(f);
            }
            else
            {
                throw new CodigoInvalidoException("Código no existe");
            }
            return true;
        }

        //SECCION PARA APROBAR ENTIDADES -- VICTOR
        // Verificar Estados para recursos (no son los mismos que para servicios)!!!
        public void aprobarRecurso(AprobarRecursoFormModel model)
        {
            foreach (AprobarRecursoDetalleModel d in model.Detalle)
            {
                if (d.Marcado)
                {
                    switch (model.TipoRecurso)
                    {
                        case 1:

                            TripulacionDAO.cambiarEstadoTripulacion(d.Codigo1, d.Codigo2, Tripulacion.ACTIVO);
                            break;
                        case 2:
                            FlotaPasajeroDAO.cambiarEstadoFlotaPasajero(d.Codigo1, d.Codigo2, FlotaPasajero.ACTIVO);
                            break;
                        case 3:
                            //FlotaCargaDAO.CambiarEstado(d.Codigo1, d.Codigo2, FlotaCarga.ACTIVO);
                            break;
                    }
                }
            }
        }

        public AprobarRecursoFormModel aprobarRecursoFormModel(int tipoRecurso)
        {
            AprobarRecursoFormModel model = new AprobarRecursoFormModel(tipoRecurso);
            switch (tipoRecurso)
            {
                case 1:
                    ICollection<Tripulacion> lista1 = TripulacionDAO.obtenerListadoPendientes();
                    foreach (Tripulacion c in lista1)
                    {
                        model.agregarItem(c.CodigoEmpleado, c.CodigoCargo, tipoRecurso, false);
                    }
                    break;
                case 2:
                    ICollection<FlotaPasajero> lista2 = FlotaPasajeroDAO.obtenerListadoPendientes();
                    foreach (FlotaPasajero c in lista2)
                    {
                        model.agregarItem(c.CodigoUnidadTransporte, c.CodigoServicio, tipoRecurso, false);
                    }
                    break;
                case 3:
                    ICollection<FlotaCarga> lista3 = FlotaCargaDAO.obtenerListadoPendientes();
                    foreach (FlotaCarga c in lista3)
                    {
                        //OJO verificar campos a mostrar.
                        model.agregarItem(c.Vehiculo.Codigo, c.Vehiculo.Codigo, tipoRecurso, false);
                    }
                    break;
            }
            return model;
        }

        public FlotaPasajero obtenerFlotaPasajero(string codUni, string codServ)
        {
            return FlotaPasajeroDAO.obtenerFlotaPasajero(codUni, codServ);
        }

        public ICollection<Empleado> buscarEmpleado(string nombres)
        {
            return TripulacionDAO.listadoEmpleados();
        }

        public ICollection<Cargo> buscarCargo(string cargo)
        {
            return null;
        }
    }
}